package com.bor.gb.db.services;

import com.bor.gb.core.services.GooglePlaceService;
import com.bor.gb.core.repo.DataService;
import com.bor.gb.db.domain.Place;
import com.bor.gb.core.exception.PlaceNotFoundException;
import com.bor.gb.db.repositories.PlaceRepository;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Nonnull;

/**
 * Created by bor on 11/15/14.
 */
@Component
public class PlaceService extends DataService<Place> {

    public static final Log log = LogFactory.getLog(PlaceService.class);

    @Autowired
    private GooglePlaceService googlePlaceService;

    @Autowired
    private PlaceRepository placeRepository;

    public Place createPlace(String country, String town, String name) {
        Place place = new Place();
        place.setCountry(country);
        place.setName(name);
        place.setTown(town);
        place = save(place);
        return place;
    }

    public Place getOrCreate(String placeId) {
        try {
            Place place = placeRepository.findByGooglePlaceId(placeId);

            if (place == null) {
                log.debug("Place was not found in local database. Checking Google Places service");
                JSONObject ret = googlePlaceService.findPlaceById(placeId).getJSONObject("result");

                if (ret != null) {
                    JSONArray addresses = ret.getJSONArray("address_components");
                    String country = getCountry(addresses);
                    String placeName =  getPlaceName(addresses);
                    place =  createPlace(country, placeName, placeName);
                    place.setGooglePlaceId(placeId);

                    log.info("Place in Google Places found: " + placeName + ". Creating place in local DB");

                    place = save(place);

                    return place;
                }else{

                    throw new PlaceNotFoundException();
                }

            }
            return place;
        } catch (Exception e) {
            log.error(e);
            throw new PlaceNotFoundException();
        }
    }

    private JSONObject getArddrByTypes(@Nonnull JSONArray addresses, String type1, String type2) throws JSONException {
        for (int i = 0; i < addresses.length(); i++) {
            String addrType1 = addresses.getJSONObject(i).getJSONArray("types").getString(0);
            String addrType2 = addresses.getJSONObject(i).getJSONArray("types").getString(1);

            if (addrType1.equals(type1) && addrType2.equals(type2)) {
                return addresses.getJSONObject(i);
            }
        }
        throw new JSONException(String.format("Address not fount by type1 %s and type2 %s", type1, type2));
    }

    private String getCountry(@Nonnull JSONArray addresses) throws JSONException {
        return getArddrByTypes(addresses, "country", "political").getString("long_name");

    }

    private String getPlaceName(@Nonnull JSONArray addresses) throws JSONException {
        return getArddrByTypes(addresses, "locality", "political").getString("short_name");

    }
/*

    /*
      "html_attributions" : [],
   "result" : {
      "address_components" : [
         {
            "long_name" : "Odessa",
            "short_name" : "Odessa",
            "types" : [ "locality", "political" ]
         },
         {
            "long_name" : "Odes'ka city council",
            "short_name" : "Odes'ka city council",
            "types" : [ "administrative_area_level_3", "political" ]
         },
         {
            "long_name" : "Odessa Oblast",
            "short_name" : "Odessa Oblast",
            "types" : [ "administrative_area_level_1", "political" ]
         },
         {
            "long_name" : "Ukraine",
            "short_name" : "UA",
            "types" : [ "country", "political" ]
         }
      ],
      "adr_address" : "\u003cspan class=\"locality\"\u003eOdessa\u003c/span\u003e, \u003cspan class=\"region\"\u003eOdessa Oblast\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eUkraine\u003c/span\u003e",
      "formatted_address" : "Odessa, Odessa Oblast, Ukraine",
      "geometry" : {
         "location" : {
            "lat" : 46.482526,
            "lng" : 30.7233095
         },
         "viewport" : {
            "northeast" : {
               "lat" : 46.60042199999999,
               "lng" : 30.8118901
            },
            "southwest" : {
               "lat" : 46.319522,
               "lng" : 30.6116849
            }
         }
      },
      "icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",
      "id" : "a00a65fe03f403210aab509c5774e9f77c2d7132",
      "name" : "Odessa",
      "place_id" : "ChIJQ0yGC4oxxkARbBfyjOKPnxI",
      "reference" : "CpQBgQAAAD0sGD8_JJhB-HAAls3FPqmJ0uvzS5kq13Ury8TDNq4Ow9mG2ThFeMuoRXW0f6JZSFrEKB6sOL_mt-PqGuStTU6G3lkX0CsFTO8cZCaJ-NqeAEeWFf7LpImuQbXhAmoMZ5jlm-gfWhfvjkN74CZdVh7rGYXwJfdb_PaiS7ISF928vJJ_mjgrWwJqe0Vnajj_zxIQab6W0_hReTG8lRmuShKjyxoUxuS_MeAStHP-KkxgxobOnZVgZLs",
      "scope" : "GOOGLE",
      "types" : [ "locality", "political" ],
      "url" : "https://maps.google.com/maps/place?q=Odessa,+Odessa+Oblast,+Ukraine&ftid=0x40c6318a0b864c43:0x129f8fe28cf2176c",
      "vicinity" : "Odessa"
   },
   "status" : "OK"
}
     */

}
